﻿#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
//#include <stdlib.h>
////2. 命名空间可以嵌套
//namespace sdglxy
//{
//	namespace ym
//	{
//		int rand = 1;
//		int Add(int left, int right)
//		{
//			return left + right;
//		}
//	} 
//	namespace zy
//	{
//		int rand = 2;
//		int Add(int left, int right)
//		{
//			return (left + right) * 10;
//		}
//	}
//} 
//int main()
//{
//	printf("%d\n", sdglxy::ym::rand);
//	printf("%d\n", sdglxy::zy::rand);
//	printf("%d\n", sdglxy::ym::Add(1, 2));
//	printf("%d\n", sdglxy::zy::Add(1, 2));
//	return 0;
//}
//namespace zy
//{
//	//⼀般开发中是⽤项目名字做命名空间名。
//	// 命名空间中可以定义变量/函数/类型
//	int rand = 10;
//	int Add(int left, int right)
//	{
//		return left + right;
//	} 
//	struct Node
//	{
//		struct Node* next;
//		int val;
//	};
//}
//int main()
//{
//	// 这⾥默认是访问的是全局的rand函数指针
//	printf("%p\n", rand);
//	printf("%d\n", rand);
//	// 这⾥指定zy命名空间中的rand
//	// ::域作用限定符，用于指向命名空间寻找所需变量、函数、类等
//	printf("%p\n", zy::rand);
//	printf("%d\n", zy::rand);
//	return 0;
//}



//#include"Stack.h"
//// 全局定义了⼀份单独的栈
//typedef struct Stack
//{
//	int a[10];
//	int top;
//}ST;
//void STInit(ST* ps) {}
//void STPush(ST* ps, int x) {}
//int main()
//{
//	// 调⽤全局的栈
//	ST st1;
//	STInit(&st1);
//	STPush(&st1, 1);
//	STPush(&st1, 2);
//	printf("%d\n", sizeof(st1));
//	// 调用zy namespace命名空间的栈
//	zy::ST st2;
//	printf("%d\n", sizeof(st2));
//	zy::STInit(&st2);
//	zy::STPush(&st2, 1);
//	zy::STPush(&st2, 2);
//	return 0;
//}

//namespace zy
//{
//	int a = 10;
//}
//// 指定命名空间访问
//int main()
//{
//	// ::域作用限定符
//	printf("%d\n", zy::a);
//	return 0;
//} 
// 
//#include<iostream>
//namespace zy
//{
//	int a = 10;
//	int b = 20;
//}
//// 展开命名空间中全部成员
//using namespace zy;
//int main()
//{
//	printf("%d\n", a);
//	printf("%d\n", b);
//	return 0;
//}
//// using将命名空间中某个成员展开
//using zy::b;
//int main()
//{
//	printf("%d\n", zy::a);
//	printf("%d\n", b);
//	return 0;
//}



//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 0;
//	double b = 0.1;
//	char c = 'x';
//	cout << a << " " << b << " " << c << endl;
//	std::cout << a << " " << b << " " << c << std::endl;
//	scanf("%d%lf", &a, &b);
//	printf("%d %lf\n", a, b);
//	// 可以自动识别变量的类型
//	cin >> a;
//	cin >> b >> c;
//	cout << a << endl;
//	cout << b << " " << c << endl;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//void Func(int a = 0)
//{
//	cout << a << endl;
//}
//int main()
//{
//	Func(); // 没有传参时，使用参数的默认值
//	Func(10); // 传参时，使用指定的实参
//	return 0;
//}


//#include <iostream>
//using namespace std;
//// 全缺省
//void Func1(int a = 10, int b = 20, int c = 30)
//{
//	cout << "a = " << a << endl;
//	cout << "b = " << b << endl;
//	cout << "c = " << c << endl << endl;
//}
//// 半缺省
//void Func2(int a, int b = 10, int c = 20)
//{
//	cout << "a = " << a << endl;
//	cout << "b = " << b << endl;
//	cout << "c = " << c << endl << endl;
//}
//int main()
//{
//	Func1();
//	Func1(1);
//	Func1(1, 2);
//	Func1(1, 2, 3);
//	Func2(100);
//	Func2(100, 200);
//	Func2(100, 200, 300);
//	return 0;
//}

//int Add(int left, int right)
//{
//	cout << "int Add(int left, int right)" << endl;
//	return left + right;
//}
//double Add(double left, double right)
//{
//	cout << "double Add(double left, double right)" << endl;
//	return left + right;
//}
//void f()
//{
//	cout << "f()" << endl;
//}
//void f(int a)
//{
//	cout << "f(int a)" << endl;
//}



//void f(int a, char b)
//{
//	cout << "f(int a,char b)" << endl;
//}
//void f(char b, int a)
//{
//	cout << "f(char b, int a)" << endl;
//}
//int main()
//{
//	f('a', 1);
//	f(1, 'a');
//	return 0;
//}
//#include<iostream>
//using namespace std;
//
//void f1()
//{
//	cout << "f()" << endl;
//}
//void f1(int a = 10)
//{
//	cout << "f(int a)" << endl;
//}
//int main()
//{
//	f1();
//	return 0;
//}

//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 0;
//	// 引⽤：b和c是a的别名
//	int& b = a;
//	int& c = a;
//	// 也可以给别名b取别名，d相当于还是a的别名
//	int& d = b;
//	++d;
//	// 这⾥取地址我们看到是⼀样的
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << &d << endl;
//	return 0;
//}

//int main()
//{
//	int a = 10;
//	// 编译报错：“ra”: 必须初始化引⽤
//	//int& ra;
//	int& b = a;
//	int c = 20;
//	// 这⾥并不是让b引⽤c，因为C++引⽤不能改变指向。
//	// 这⾥是⼀个赋值，本质上是将c赋值给a。
//	b = c;
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	return 0;
//}


//#include<iostream>
//using namespace std;
//通过引用传参来进行交换，不再需要操作指针。
//void Swap(int& rx, int& ry)
//{
//	int tmp = rx;
//	rx = ry;
//	ry = tmp;
//}
//int main()
//{
//	int x = 0, y = 1;
//	cout << x << " " << y << endl;
//	Swap(x, y);
//	cout << x << " " << y << endl;
//	return 0;
//}


//#include<iostream>
//#include<assert.h>
//using namespace std;
//typedef int STDataType;
//typedef struct Stack
//{
//	STDataType* a;
//	int top;
//	int capacity;
//}ST;
//void STInit(ST& rs, int n = 4)
//{
//	rs.a = (STDataType*)malloc(n * sizeof(STDataType));
//	rs.top = 0;
//	rs.capacity = n;
//}
//// 栈顶
//void STPush(ST& rs, STDataType x)
//{
//	// 满了， 扩容
//	if (rs.top == rs.capacity)
//	{
//		printf("扩容\n");
//		int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;
//		STDataType* tmp = (STDataType*)realloc(rs.a, newcapacity *
//			sizeof(STDataType));
//		if (tmp == NULL)
//		{
//			perror("realloc fail");
//			return;
//		}
//		rs.a = tmp;
//		rs.capacity = newcapacity;
//	}
//	rs.a[rs.top] = x;
//	rs.top++;
//}
//// int STTop(ST& rs)
//int& STTop(ST& rs)//传引用返回
//{
//	assert(rs.top > 0);
//	return rs.a[rs.top-1];
//}
//int main()
//{
//	// 调用全局的Stack
//	ST st1;
//	STInit(st1);
//	STPush(st1, 1);
//	STPush(st1, 2);
//	cout << STTop(st1) << endl;
//	//传引用返回的作用，返回值可修改，因为返回引用相当于返回的变量，而非常量。
//	STTop(st1) += 10;
//	cout << STTop(st1) << endl;
//	return 0;
//}



//#include<iostream>
//using namespace std;
//typedef struct SeqList
//{
//	int a[10];
//	int size;
//}SLT;
//// ⼀些主要⽤C代码实现版本数据结构教材中，使⽤C++引⽤替代指针传参，⽬的是简化程序，避开复杂的指针，但是很多同学没学过引⽤，导致⼀头雾⽔。
//void SeqPushBack(SLT& sl, int x)
//{}
//typedef struct ListNode
//{
//	int val;
//	struct ListNode* next;
//}LTNode, * PNode;
//// 指针变量也可以取别名，这⾥LTNode*& phead就是给指针变量取别名
//// 这样就不需要用⼆级指针了，相对而言简化了程序
////void ListPushBack(LTNode** phead, int x)
////void ListPushBack(LTNode*& phead, int x)
//void ListPushBack(PNode& phead, int x)//这里的PNode 就是 LTNode*
//{
//	PNode newnode = (PNode)malloc(sizeof(LTNode));
//	newnode->val = x;
//	newnode->next = NULL;
//	if (phead == NULL)
//	{
//		phead = newnode;
//	}
//	else
//	{
//		//...
//	}
//}
//	int main()
//	{
//		//LTNode* plist = NULL;
//		PNode plist = NULL;
//		ListPushBack(plist, 1);
//		return 0;
//	}

//int main()
//{
//	const int a = 10;
//
//	// 编译报错：error C2440: “初始化”: 无法从“const int”转换为“int &”	
//	// 这⾥的引用是对a访问权限的放大
//	//int& ra = a;
//	
//	// 这样才可以
//	const int& ra = a;
//	// 编译报错：error C3892: “ra”: 不能给常量赋值
//	//ra++;
//	
//	// 这⾥的引⽤是对b访问权限的缩⼩
//	int b = 20;
//	const int& rb = b;
//	// 编译报错：error C3892: “rb”: 不能给常量赋值
//	//rb++;
//	return 0;
//}
//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 10;
//	const int& ra = 30;
//	// 编译报错: “初始化”: ⽆法从“int”转换为“int &”
//	// int& rb = a * 3;
//	const int& rb = a * 3;
//	double d = 12.34;
//	// 编译报错：“初始化”: ⽆法从“double”转换为“int &”
//	// int& rd = d;
//	const int& rd = d;
//	return 0;
//}

//#include<iostream>
//using namespace std;
//inline int Add(int x, int y)
//{
//	int ret = x + y;
//	ret += 1;
//	ret += 1;
//	ret += 1;
//	ret += 1;
//	ret += 1;
//	ret += 1;
//
//	return ret;
//}
//int main()
//{
//// 可以通过汇编观察程序是否展开
//// 有call Add语句就是没有展开，没有就是展开了
//int ret = Add(1, 2);
//cout << Add(1, 2) * 5 << endl;
//return 0;
//}

//#include<iostream>
//using namespace std;
//// 实现⼀个ADD宏函数的常⻅问题
////#define ADD(int a, int b) return a + b;
////#define ADD(a, b) a + b;
////#define ADD(a, b) (a + b)
//// 正确的宏实现
//#define ADD(a, b) ((a) + (b))
//// 为什么不能加分号?
//// 为什么要加外⾯的括号?
//// 为什么要加⾥⾯的括号?
//int main()
//{
//	int ret = ADD(1, 2);
//	cout << ADD(1, 2) << endl;
//	cout << ADD(1, 2) * 5 << endl;
//	int x = 1, y = 2;
//	ADD(x & y, x | y); // -> (x&y+x|y)
//	return 0;
//}

//// F.h
//#include <iostream>
//using namespace std;
//inline void f(int i);
//// F.cpp
//#include "F.h"
//void f(int i)
//{
//	cout << i << endl;
//}
//// main.cpp
//#include "F.h"
//int main()
//{
//	// 链接错误：⽆法解析的外部符号 "void __cdecl f(int)" (?f@@YAXH@Z)
//	f(10);
//	return 0;
////}
//
//#include<iostream>
//using namespace std;
//void f(int x)
//{
//	cout << "f(int x)" << endl;
//}
//void f(int* ptr)
//{
//	cout << "f(int* ptr)" << endl;
//}
//int main()
//{
//	f(0);
//	// 本想通过f(NULL)调⽤指针版本的f(int*)函数，但是由于NULL被定义成0，调⽤了f(intx)，因此与程序的初衷相悖。
//	f(NULL);
//	f((int*)NULL);
//
//	// 编译报错：error C2665: “f”: 2 个重载中没有⼀个可以转换所有参数类型
//	// f((void*)NULL);
//	
//	f(nullptr);
//	return 0;
//}